using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Configuration;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Xml;
using System.Globalization;
using System.Collections;
using System.Workflow.Activities.Rules;
using System.Workflow.ComponentModel.Compiler;
using System.Workflow.ComponentModel.Serialization;
using System.Data.SqlClient;
using CSF.Communications.Sdp.ServiceLogic.Entities;

namespace CSF.Communications.Sdp.ServiceLogic.WFUtility
{
       public class RulesUtility
    {

        private string currentStateField;

        private string currentResultCodeField;

        private string calledStatesField;

        private string nextStatesField;

        private string mapsField;

        private string timeoutsField;

        private string rulePolicyStatusField;

        private string resultCodeToSbeField;

        private string errorMessageToSbeField;

        private string csfContextField;

        private bool isUSMRequiredField;

        private bool isSSORequiredField;

        private string usmServiceIdField;

        private string ssoApplicationNameField;

        string connectionString = @"Initial Catalog=Rules;Data Source=.\SQLExpress;Integrated Security=SSPI;";
        WorkflowMarkupSerializer serializer = new WorkflowMarkupSerializer();
        RuleSet ruleSet = null;
        RuleValidation ruleValidation = null;
        RuleExecution ruleExecution = null;


        /// <remarks/>
        [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified, DataType = "token")]
        public string UsmServiceId
        {
            get
            {
                return this.usmServiceIdField;
            }
            set
            {
                this.usmServiceIdField = value;
            }
        }



        /// <remarks/>
        [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified, DataType = "token")]
        public string SsoApplicationName
        {
            get
            {
                return this.ssoApplicationNameField;
            }
            set
            {
                this.ssoApplicationNameField = value;
            }
        }   
           
        /// <remarks/>
        [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified, DataType = "token")]
        public bool IsUSMRequired
        {
            get
            {
                return this.isUSMRequiredField;
            }
            set
            {
                this.isUSMRequiredField = value;
            }
        }

        /// <remarks/>
        [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified, DataType = "token")]
        public bool IsSSORequired
        {
            get
            {
                return this.isSSORequiredField;
            }
            set
            {
                this.isSSORequiredField = value;
            }
        }

        /// <remarks/>
        [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified, DataType = "token")]
        public string CurrentState
        {
            get
            {
                return this.currentStateField;
            }
            set
            {
                this.currentStateField = value;
            }
        }

        /// <remarks/>
        [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified, DataType = "integer")]
        public string CurrentResultCode
        {
            get
            {
                return this.currentResultCodeField;
            }
            set
            {
                this.currentResultCodeField = value;
            }
        }

        /// <remarks/>
        [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified, DataType = "token")]
        public string CalledStates
        {
            get
            {
                return this.calledStatesField;
            }
            set
            {
                this.calledStatesField = value;
            }
        }

        /// <remarks/>
        [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
        public string NextStates
        {
            get
            {
                return this.nextStatesField;
            }
            set
            {
                this.nextStatesField = value;
            }
        }

        /// <remarks/>
        [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
        public string Maps
        {
            get
            {
                return this.mapsField;
            }
            set
            {
                this.mapsField = value;
            }
        }

        /// <remarks/>
        [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified, DataType = "token")]
        public string Timeouts
        {
            get
            {
                return this.timeoutsField;
            }
            set
            {
                this.timeoutsField = value;
            }
        }

        /// <remarks/>
        [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
        public string RulePolicyStatus
        {
            get
            {
                return this.rulePolicyStatusField;
            }
            set
            {
                this.rulePolicyStatusField = value;
            }
        }

        /// <remarks/>
        [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified, DataType = "integer")]
        public string ResultCodeToSbe
        {
            get
            {
                return this.resultCodeToSbeField;
            }
            set
            {
                this.resultCodeToSbeField = value;
            }
        }

        /// <remarks/>
        [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
        public string ErrorMessageToSbe
        {
            get
            {
                return this.errorMessageToSbeField;
            }
            set
            {
                this.errorMessageToSbeField = value;
            }
        }

        /// <remarks/>
        [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
        public string CsfContext
        {
            get
            {
                return this.csfContextField;
            }
            set
            {
                this.csfContextField = value;
            }
        }

        public RulesUtility(CSF_MID mid,string policyName)
        {
            //ConnectionStringSettingsCollection connectionStringSettingsCollection = ConfigurationManager.ConnectionStrings;
            //foreach (ConnectionStringSettings connectionStringSettings in connectionStringSettingsCollection)
            //{
            //    if (string.CompareOrdinal(connectionStringSettings.Name, "RuleSetStoreConnectionString") == 0)
            //        connectionString = connectionStringSettings.ConnectionString;
            //}
            this.currentStateField = mid.RoutingData.CurrentState;
            this.currentResultCodeField = mid.RoutingData.CurrentResultCode;
            this.rulePolicyStatusField = RulePolicyStatusType.notstarted.ToString();
            this.resultCodeToSbeField = mid.RoutingData.ResultCodeToSbe;
            this.errorMessageToSbeField = "";
            this.csfContextField = " ";

            ruleSet = GetRuleSetFromDB(policyName);
            if (null != ruleSet)
            {
              //  ValidateRuleSet();
              //  ExecuteRule();
            }
            else
            {
              //  MessageBox.Show("RuleSet is Null. Make sure you run the install scripts and you are pointing to the correct database. \n ConnectionString=" + connectionString, "Order Entry", MessageBoxButtons.OK, MessageBoxIcon.Error);
               // this.Close();
            }

        }

        private void ValidateRuleSet()
        {
            ruleValidation = new RuleValidation(this.GetType(), null);
            if ((null != ruleValidation) && (!ruleSet.Validate(ruleValidation)))
            {
                string errors = "";
                foreach (ValidationError validationError in ruleValidation.Errors)
                    errors = errors + validationError.ErrorText + "\n";
              //  MessageBox.Show("Validation Errors \n" + errors);
            }
            else
            {
                ruleExecution = new RuleExecution(ruleValidation, this);
            }
        }

        private void ExecuteRule()
        {
            if (null != ruleExecution)
            {
                try
                {
                    ruleSet.Execute(ruleExecution);
                }
                catch (Exception e)
                {
                   // MessageBox.Show("Exception thrown \n" + e.Message);
                }
            }
            else
            {
               // MessageBox.Show("RuleExecution is null");
            }
        }

        private RuleSet GetRuleSetFromDB(string ruleSetName)
        {
            SqlConnection sqlConn = new SqlConnection(connectionString);
            sqlConn.Open();
            string commandString = "SELECT TOP 1 * FROM RuleSet WHERE Name= '" + ruleSetName + "' ORDER BY ModifiedDate DESC";
            SqlCommand command = new SqlCommand(commandString, sqlConn);
            SqlDataReader reader = command.ExecuteReader();

            RuleSet ruleSet = null;

            if (reader.HasRows)
            {
                reader.Read();
                ruleSet = DeserializeRuleSet(reader.GetString(3));
            }
            sqlConn.Close();
            return ruleSet;
        }

        private string SerializeRuleSet(RuleSet ruleSet)
        {
            StringBuilder ruleDefinition = new StringBuilder();

            if (ruleSet != null)
            {
                try
                {
                    StringWriter stringWriter = new StringWriter(ruleDefinition, CultureInfo.InvariantCulture);
                    XmlTextWriter writer = new XmlTextWriter(stringWriter);
                    serializer.Serialize(writer, ruleSet);
                    writer.Flush();
                    writer.Close();
                    stringWriter.Flush();
                    stringWriter.Close();
                }
                catch (Exception ex)
                {
                   // MessageBox.Show(string.Format(CultureInfo.InvariantCulture, "Error serializing RuleSet: '{0}'. \r\n\n{1}", ruleSet.Name, ex.Message));
                }
            }
            else
            {
               // MessageBox.Show(String.Format(CultureInfo.InvariantCulture, "Error serializing RuleSet: '{0}'. RuleSet is null", ruleSet.Name));
            }

            return ruleDefinition.ToString();
        }

        private RuleSet DeserializeRuleSet(string ruleSetXmlDefinition)
        {
            if (!String.IsNullOrEmpty(ruleSetXmlDefinition))
            {
                StringReader stringReader = new StringReader(ruleSetXmlDefinition);
                XmlTextReader reader = new XmlTextReader(stringReader);
                return serializer.Deserialize(reader) as RuleSet;
            }
            else
            {
                return null;
            }
        }


        public CSF_MID ExecutePolicy(CSF_MID mid, string policyName, int majorVersion, int minorVersion)
        {
            
            try
            {
                ValidateRuleSet();
                ExecuteRule();

                mid.RoutingData.CurrentState = this.CurrentState;
                mid.RoutingData.CurrentResultCode = this.CurrentResultCode;
                mid.RoutingData.NextStates = this.NextStates;
                mid.RoutingData.ResultCodeToSbe = this.ResultCodeToSbe;
                mid.RoutingData.Maps = this.Maps;
                mid.RoutingData.IsSSORequired = this.IsSSORequired;
                mid.RoutingData.IsUSMRequired = this.IsUSMRequired;
                mid.RoutingData.SsoApplicationName = this.SsoApplicationName;
                mid.RoutingData.UsmServiceId = this.UsmServiceId;

                if (mid.RoutingData.NextStates != "End")
                {
                    mid.RoutingData.RulePolicyStatus = RulePolicyStatusType.inprogress;
                }
                else
                {
                    mid.RoutingData.RulePolicyStatus = RulePolicyStatusType.completed;
                }
               
                return mid;
            }
            catch(Exception ex)
            {
                System.Diagnostics.EventLog.WriteEntry("UI",ex.Message);
                return mid;
            }

        }


    }

}
